//
// Created by TheMorbidArk on 2022/11/3.
//

#ifndef VANTIDEL_CPP_PARSER_H
#define VANTIDEL_CPP_PARSER_H

#include "common.h"
#include "vm.h"
#include "Class.h"
#include "compiler.h"

// 查看 TOKEN 类型
#define PEEK_TOKEN(parserPtr) parserPtr->curToken.type

uint32_t getByteNumOfEncodeUtf8(int value);

uint8_t encodeUtf8(uint8_t *buf, int value);

typedef enum {
    TOKEN_UNKNOWN,
    // 数据类型
    TOKEN_NUM,           //数字
    TOKEN_STRING,           //字符串
    TOKEN_ID,               //变量名
    TOKEN_INTERPOLATION,     //内嵌表达式

    // 关键字(系统保留字)
    TOKEN_VAR,           //'var'
    TOKEN_FUN,           //'fun'
    TOKEN_IF,           //'if'
    TOKEN_ELSE,               //'else'
    TOKEN_TRUE,               //'true'
    TOKEN_FALSE,               //'false'
    TOKEN_WHILE,               //'while'
    TOKEN_FOR,               //'for'
    TOKEN_BREAK,               //'break'
    TOKEN_CONTINUE,         //'continue'
    TOKEN_RETURN,           //'return'
    TOKEN_NULL,               //'null'

    //以下是关于类和模块导入的token
    TOKEN_CLASS,               //'class'
    TOKEN_THIS,               //'this'
    TOKEN_STATIC,           //'static'
    TOKEN_IS,           // 'is'
    TOKEN_SUPER,               //'super'
    TOKEN_IMPORT,           //'import'

    //分隔符
    TOKEN_COMMA,           //','
    TOKEN_COLON,           //':'
    TOKEN_LEFT_PAREN,       //'('
    TOKEN_RIGHT_PAREN,       //')'
    TOKEN_LEFT_BRACKET,       //'['
    TOKEN_RIGHT_BRACKET,       //']'
    TOKEN_LEFT_BRACE,       //'{'
    TOKEN_RIGHT_BRACE,       //'}'
    TOKEN_DOT,           //'.'
    TOKEN_DOT_DOT,       //'..'

    //简单双目运算符
    TOKEN_ADD,           //'+'
    TOKEN_SUB,           //'-'
    TOKEN_MUL,           //'*'
    TOKEN_DIV,           //'/'
    TOKEN_MOD,           //'%'

    //赋值运算符
    TOKEN_ASSIGN,       //'='

    // 位运算符
    TOKEN_BIT_AND,       //'&'
    TOKEN_BIT_OR,       //'|'
    TOKEN_BIT_NOT,       //'~'
    TOKEN_BIT_SHIFT_RIGHT,  //'>>'
    TOKEN_BIT_SHIFT_LEFT,   //'<<'

    // 逻辑运算符
    TOKEN_LOGIC_AND,       //'&&'
    TOKEN_LOGIC_OR,       //'||'
    TOKEN_LOGIC_NOT,       //'!'

    //关系操作符
    TOKEN_EQUAL,           //'=='
    TOKEN_NOT_EQUAL,       //'!='
    TOKEN_GREATE,       //'>'
    TOKEN_GREATE_EQUAL,       //'>='
    TOKEN_LESS,           //'<'
    TOKEN_LESS_EQUAL,       //'<='

    TOKEN_QUESTION,       //'?'

    //文件结束标记,仅词法分析时使用
    TOKEN_EOF           //'EOF'
} TokenType;

typedef struct {
    TokenType type;
    const char *start;
    uint32_t length;
    uint32_t lineNo;
    Value value;
} Token;

class Parser {
public:
    const char *file;
    const char *sourceCode;
    const char *nextCharPtr;
    char curChar;
    Token curToken{};
    Token preToken{};

    ObjModule *curModule;   // 正在编译的模块
    CompileUnit* curCompileUnit;   // 当前编译单元

    //处于内嵌表达式之中时,期望的右括号数量.
    //用于跟踪小括号对儿的嵌套
    int interpolationExpectRightParenNum;
    Parser* parent; // 指向父parser
    VM *vm;

    // 向前看一个字符(不获取)
    static char LookAheadChar(Parser *parser);

    // 获取下一字符
    static void GetNextChar(Parser *parser);

    // 查看下一个字符是否为期望的,如果是就读进来,返回true,否则返回false
    static bool MatchNextChar(Parser *parser, char expectedChar);

    // 跳过连续的空白字符
    static void SkipBlanks(Parser *parser);

    // 解析标识符
    static void ParseId(Parser *parser, TokenType type);

    // 解析unicode码点
    static void ParseUnicodeCodePoint(Parser *parser, ByteBuffer *buf);

    // 解析字符串
    static void ParseString(Parser *parser);

    //解析十六进制数字
    static void ParseHexNum(Parser *parser);

    //解析十进制数字
    static void ParseDecNum(Parser *parser);

    //解析八进制
    static void ParseOctNum(Parser *parser);

    //解析八进制 十进制 十六进制 仅支持前缀形式,后缀形式不支持
    static void ParseNum(Parser *parser);

    // 跳过一行
    static void SkipAline(Parser *parser);

    // 跳过行注释或区块注释
    static void SkipComment(Parser *parser);

    // 获取下一个token
    static void GetNextToken(Parser *parser);

    // 若当前token为expected则读入下一个token并返回true, 否则不读入token且返回false
    static bool MatchToken(Parser *parser, TokenType expected);

    // 断言当前token为expected并读入下一token,否则报错errMsg
    static void ConsumeCurToken(Parser *parser, TokenType expected, const char *errMsg);

    // 断言下一个token为expected,否则报错errMsg
    static void ConsumeNextToken(Parser *parser, TokenType expected, const char *errMsg);

    Parser();

    Parser(VM *vm, const char *file, const char *sourceCode, ObjModule *objModule);

};

#endif //VANTIDEL_CPP_PARSER_H
